package com.business.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.xserver.common.util.DateUtil;
import org.xserver.component.redis.RedisTemplate;
import org.xserver.component.redis.util.RedisConstant;

@Service
public class AccessTokenService {

	private static final Logger log = LoggerFactory
			.getLogger(AccessTokenService.class);
	@Resource
	private RedisTemplate reidsTemplate;
	@Resource
	private RedisConstant redisConstant;

	public String getUseridByAccessToken(String accessToken) {
		log.debug("getUseridByAccessToken:" + accessToken);
		try {
			Map<String, String> result = reidsTemplate.hashGet(accessToken);
			if (result == null || result.size() == 0) {
				log.warn("getUseridByAccessToken have no result");
				return null;
			} else {
				return result.get(RedisConstant.USER_ID);
			}
		} catch (Exception ex) {
			log.error("getUseridByAccessToken err {},{}", accessToken, ex);
			return null;
		}
	}

	private void setResult(String accessToken, String userId) throws Exception {

		Map<String, String> newResult = new HashMap<String, String>();
		// step1 update or replace new one
		newResult.put(RedisConstant.CREATE_TIME,
				DateUtil.format(new Date(), DateUtil.DF_yyyyMMddHHmmss));
		newResult.put(RedisConstant.ACCESS_TOKEN, accessToken);
		reidsTemplate.hashSet(userId, newResult);

		newResult.clear();

		// step2 create new one and set key timeout
		newResult.put(RedisConstant.USER_ID, userId);
		newResult.put(RedisConstant.CREATE_TIME,
				DateUtil.format(new Date(), DateUtil.DF_yyyyMMddHHmmss));
		reidsTemplate.hashSet(accessToken, newResult);
		reidsTemplate.expire(accessToken, RedisConstant.accessTokenTimeout);
	}

	public String getAccessTokenByUser(String userId) {

		try {
			Map<String, String> result = reidsTemplate.hashGet(userId);
			UUID uuid = UUID.randomUUID();
			String accessToken = String.valueOf(uuid);
			if (result == null || result.size() == 0) {
				setResult(accessToken, userId);
				return accessToken;
			} else {
				// check this token if overdue
				String createTime = result.get(RedisConstant.CREATE_TIME);
				Date d1 = DateUtil.parser(createTime,
						DateUtil.DF_yyyyMMddHHmmss);
				Date d2 = new Date();
				long t1 = d1.getTime();
				long t2 = d2.getTime();
				if (t2 - t1 >= RedisConstant.accessTokenTimeout * 1000) {
					setResult(accessToken, userId);
					return accessToken;
				} else {
					return result.get(RedisConstant.ACCESS_TOKEN);
				}
			}

		} catch (Exception ex) {
			log.error("getRomdomAccessCode occur error", ex);
		}
		return null;
	}

}
